package com.heima.comment.service.impl;


import com.heima.apis.user.IUserClient;
import com.heima.comment.service.CommentRepayService;
import com.heima.common.aliyun.GreenTextScan;
import com.heima.model.comment.dtos.RepayDto;
import com.heima.model.comment.dtos.RepayLikeDto;
import com.heima.model.comment.dtos.RepaySaveDto;
import com.heima.model.comment.pojos.Comment;
import com.heima.model.comment.pojos.DataRecord;
import com.heima.model.comment.pojos.Repay;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.user.pojos.ApUser;
import com.heima.utils.thread.AppThreadLocalUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.FindAndModifyOptions;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
@Transactional
public class CommentRepayServiceImpl implements CommentRepayService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private IUserClient userClient;

    @Autowired
    private GreenTextScan greenTextScan;

    /**
     * 保存回复
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult save(RepaySaveDto dto) {

        // 判断是否是游客登陆 摆烂先不做

        // 判断回复数据是否存在
        if (dto == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }

        // 获取当前登陆用户id
        Integer userId = AppThreadLocalUtil.getUser().getId();
        // 调用远程feign接口获取当前登陆用户数据
        ApUser user = userClient.findApUser(userId);

        // 构造回复对象
        Repay repay = new Repay();
        // 作者id
        repay.setAuthorId(Long.valueOf(userId));
        // 作者名字
        repay.setAuthorName(user.getName());
        // 评论id
        repay.setCommentId(dto.getCommentId());
        // 回复内容
        repay.setContent(dto.getContent());
        // 回复点赞数
        repay.setLikes(0);
        // 回复时间
        repay.setCreatedTime(System.currentTimeMillis());
        // 头像
        repay.setImage("http://192.168.200.130:9000/leadnews/2022/03/22/be209cdca9e54500ba1f8b49f6482d0c.jpg");

        // 评论内容字数检测 不能大于140
        if (dto.getContent().length() > 140) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "回复字数不能超过140字");
        }

        // 回复内容垃圾检测
        try {
            Map map = greenTextScan.greeTextScan(dto.getContent());
            if (map == null) {
                // 通过检测 调用MongoTemplate保存回复
                mongoTemplate.save(repay);
            }
        } catch (Exception e) {
            throw new RuntimeException("回复内容不合法");
        }

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }


    private static final Short MAX_PAGE_SIZE = 50;

    /**
     * 查询回复列表
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult load(RepayDto dto) {

        // 校验参数
        // 分页校验
        Integer size = dto.getSize();
        if (size == null || size == 0) {
            size = 10;
        }
        size = Math.min(size, MAX_PAGE_SIZE);
        dto.setSize(size);

        if (dto.getMinDate() == null) dto.setMinDate(new Date());


        // 构造查询条件
        Criteria criteria = Criteria.where("commentId").is(dto.getCommentId()).and("createdTime").lt(dto.getMinDate().getTime());
        Query queryLimit = new Query(criteria).limit(size).with(Sort.by(Sort.Order.desc("createdTime")));
        List<Repay> repayList = mongoTemplate.find(queryLimit, Repay.class);

        return ResponseResult.okResult(repayList);
    }


    /**
     * 回复点赞和取消点赞
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult like(RepayLikeDto dto) {

        // 构造查询条件
        Query query = Query.query(Criteria.where("repayId").is(dto.getCommentRepayId())
                .and("userId").is(AppThreadLocalUtil.getUser().getId()));

        // 判断是否已点赞
        boolean exists = mongoTemplate.exists(query, DataRecord.class);

        if (!exists) {
            // 保存点赞数据
            Update update = new Update();
            update.set("operation", (short) 0);
            DataRecord record = new DataRecord();
            record.setUserId(AppThreadLocalUtil.getUser().getId());
            record.setRepayId(dto.getCommentRepayId());
            record.setType(1);
            record.setOperation((short) 0);
            mongoTemplate.save(record);

            // 更新回复表中的likes字段  +1
            Query repayQuery = Query.query(Criteria.where("id").is(dto.getCommentRepayId()));
            Update repayUpdate = new Update();
            repayUpdate.inc("likes", 1);
            FindAndModifyOptions options = new FindAndModifyOptions();
            options.returnNew(true);
            Repay modify = mongoTemplate.findAndModify(repayQuery, repayUpdate, options, Repay.class);
            Integer likes = modify.getLikes();
        } else {
            // 删除点赞数据
            Criteria criteria = Criteria.where("repayId").is(dto.getCommentRepayId())
                    .and("userId").is(AppThreadLocalUtil.getUser().getId());
            Query recordQuery = Query.query(criteria);
            mongoTemplate.remove(query, DataRecord.class);

            // 更新回复表中的likes字段  -1
            Query repayQuery = Query.query(Criteria.where("id").is(dto.getCommentRepayId()));
            Update repayUpdate = new Update();
            repayUpdate.inc("likes", -1);
            FindAndModifyOptions options = new FindAndModifyOptions();
            options.returnNew(true);
            Repay modify = mongoTemplate.findAndModify(repayQuery,repayUpdate, options, Repay.class);
            Integer likes = modify.getLikes();
        }

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);

    }
}

